/**
 * 
 */
package org.xlab.baseframework.web.component;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.xlab.baseframework.domain.ISystemUserDomain;
import org.xlab.baseframework.domain.SystemCode;
import org.xlab.baseframework.domain.view.SystemCodeVO;
import org.xlab.baseframework.exception.SystemCodeDuplicateException;
import org.xlab.baseframework.exception.SystemCodeNotFoundException;
import org.xlab.baseframework.service.api.ISystemCodeService;
import org.xlab.baseframework.system.Declare;
import org.xlab.baseframework.web.util.ItemUtil;

import com.jensjansson.pagedtable.PagedTable;
import com.vaadin.data.Item;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window.CloseEvent;
import com.vaadin.ui.Window.CloseListener;

/**
 * @author MaKuBEX
 * 
 */
public class CodeFunctionLayout extends AbstractBaseHorizontalSplitPanel {

	/**
	 * @serialField
	 */
	private static final long serialVersionUID = 5927152744153787830L;

	public PagedTable codeTable;
	public VerticalLayout buttons;

	@Autowired(required = true)
	@Qualifier("bpf_systemCodeService")
	private ISystemCodeService systemCodeService;
	private BeanItemContainer<SystemCodeVO> allSystemCode;
	@Autowired(required = true)
	@Qualifier("bpf_codeEditWindow")
	private CodeEditWindow codeEditWindow;
	@Autowired(required = true)
	@Qualifier("bpf_codeAddWindow")
	private CodeAddWindow codeAddWindow;

	/**
	 * <p>
	 * 默认构造函数
	 * </p>
	 * 
	 * @throws SystemCodeNotFoundException
	 */
	public CodeFunctionLayout() {
		super();
		super.setMargin(false);
		super.setWidth(Declare.HUNDRED_PERCENT);
	}

	/**
	 * @see com.vaadin.ui.AbstractComponentContainer#attach()
	 */
	@SuppressWarnings("serial")
	public void attach() {
		super.attach();
		this.codeTable = new PagedTable();
		this.codeTable.setSelectable(true);
		this.codeTable.setImmediate(true);
		this.codeTable.setWidth(Declare.HUNDRED_PERCENT);
		try {
			List<SystemCode> codeList = this.systemCodeService.findAll();
			List<SystemCodeVO> voList = this.systemCodeService
					.convertToVOList(codeList);
			allSystemCode = new BeanItemContainer<SystemCodeVO>(
					SystemCodeVO.class, voList);
			this.codeTable.setContainerDataSource(allSystemCode);
			this.codeTable.setVisibleColumns(new String[] {
					SystemCodeVO.FIELD_CODE, SystemCodeVO.FIELD_S_CATEGORY,
					SystemCodeVO.FIELD_DESCRIPTION,
					SystemCodeVO.FIELD_SEQUENCE, SystemCodeVO.FIELD_DELETED,
					SystemCodeVO.FIELD_CREATED_BY_NAME,
					SystemCodeVO.FIELD_S_CREATED_TIME,
					SystemCodeVO.FIELD_LASTUPDATED_BY_NAME,
					SystemCodeVO.FIELD_S_LASTUPDATED_TIME });
			this.codeTable.setPageLength(25);
		} catch (SystemCodeNotFoundException e) {
			e.printStackTrace();
		}

		VerticalLayout left = new VerticalLayout();
		left.setSizeFull();
		left.addComponent(this.codeTable);
		left.addComponent(this.codeTable.createControls());
		this.codeTable.setSizeFull();

		this.buttons = new VerticalLayout();
		this.buttons.setSpacing(true);
		this.buttons.setMargin(true);

		final Button add = new Button("Add");
		final Button edit = new Button("Edit");
		edit.setEnabled(false);
		final Button disable = new Button("Disable");
		disable.setEnabled(false);
		final Button enable = new Button("Enable");
		enable.setEnabled(false);

		this.buttons.addComponent(add);
		this.buttons.addComponent(edit);
		this.buttons.addComponent(disable);
		this.buttons.addComponent(enable);
		this.buttons.setWidth(120f, UNITS_PIXELS);

		super.addComponent(left);
		super.addComponent(this.buttons);
		super.setSplitPosition(140f, UNITS_PIXELS, true);

		this.codeTable.addListener(new Table.ValueChangeListener() {
			public void valueChange(ValueChangeEvent event) {
				SystemCodeVO codeVO = (SystemCodeVO) event.getProperty()
						.getValue();
				if (codeVO == null) {
					edit.setEnabled(false);
					disable.setEnabled(false);
					enable.setEnabled(false);
				} else if (codeVO.isDeleted()) {
					disable.setEnabled(false);
					enable.setEnabled(true);
					edit.setEnabled(true);
				} else {
					disable.setEnabled(true);
					enable.setEnabled(false);
					edit.setEnabled(true);
				}
			}
		});

		codeAddWindow.addListener(new CloseListener() {
			
			public void windowClose(CloseEvent e) {
				System.out.println(e.getWindow().getData());
				allSystemCode.addBean((SystemCodeVO) e.getWindow().getData());
			}
		});
		
		add.addListener(new ClickListener() {

			public void buttonClick(ClickEvent event) {
				codeAddWindow.setUiContainer(CodeFunctionLayout.this.codeTable
						.getContainerDataSource());
				codeAddWindow.setWidth(500f, UNITS_PIXELS);
				CodeFunctionLayout.super.getWindow().addWindow(codeAddWindow);
			}
		});

		edit.addListener(new ClickListener() {
			public void buttonClick(ClickEvent event) {
				Item editItem = CodeFunctionLayout.this.codeTable
						.getItem(CodeFunctionLayout.this.codeTable.getValue());
				codeEditWindow.setEditItem(editItem);
				codeEditWindow.setWidth(500f, UNITS_PIXELS);
				CodeFunctionLayout.super.getWindow().addWindow(codeEditWindow);
			}
		});

		disable.addListener(new ClickListener() {
			public void buttonClick(ClickEvent event) {
				SystemCodeVO codeVO = (SystemCodeVO) CodeFunctionLayout.this.codeTable
						.getValue();
				SystemCode codeInstance = null;
				try {
					codeInstance = CodeFunctionLayout.this.systemCodeService
							.findByCode(codeVO.getCode(), true);
					CodeFunctionLayout.this.systemCodeService.deleteSystemCode(
							codeInstance,
							(ISystemUserDomain) CodeFunctionLayout.super
									.getApplication().getUser());
					codeVO = CodeFunctionLayout.this.systemCodeService
							.convertToVO(codeInstance);
					ItemUtil.updateProperties(CodeFunctionLayout.this.codeTable
							.getItem(CodeFunctionLayout.this.codeTable
									.getValue()), new BeanItem<SystemCodeVO>(
							codeVO));
					CodeFunctionLayout.this.codeTable.setValue(codeVO);
					disable.setEnabled(false);
					enable.setEnabled(true);
				} catch (SystemCodeNotFoundException e) {
					e.printStackTrace();
				} catch (SystemCodeDuplicateException e) {
					e.printStackTrace();
				}
			}
		});

		enable.addListener(new ClickListener() {
			public void buttonClick(ClickEvent event) {
				SystemCodeVO codeVO = (SystemCodeVO) CodeFunctionLayout.this.codeTable
						.getValue();
				SystemCode codeInstance;
				try {
					codeInstance = CodeFunctionLayout.this.systemCodeService
							.findByCode(codeVO.getCode(), false);
					CodeFunctionLayout.this.systemCodeService
							.restoreSystemCode(
									codeInstance,
									(ISystemUserDomain) CodeFunctionLayout.super
											.getApplication().getUser());
					codeVO = CodeFunctionLayout.this.systemCodeService
							.convertToVO(codeInstance);
					ItemUtil.updateProperties(CodeFunctionLayout.this.codeTable
							.getItem(CodeFunctionLayout.this.codeTable
									.getValue()), new BeanItem<SystemCodeVO>(
							codeVO));
					CodeFunctionLayout.this.codeTable.setValue(codeVO);
					disable.setEnabled(true);
					enable.setEnabled(false);
				} catch (SystemCodeNotFoundException e) {
					e.printStackTrace();
				} catch (SystemCodeDuplicateException e) {
					e.printStackTrace();
				}
			}
		});

	}

	/**
	 * @param codeEditWindow
	 *            the codeEditWindow to set
	 */
	public void setCodeEditWindow(CodeEditWindow codeEditWindow) {
		this.codeEditWindow = codeEditWindow;
	}

	/**
	 * @param systemCodeService
	 *            the systemCodeService to set
	 */
	public void setSystemCodeService(ISystemCodeService systemCodeService) {
		this.systemCodeService = systemCodeService;
	}

	/**
	 * @param codeAddWindow
	 *            the codeAddWindow to set
	 */
	public void setCodeAddWindow(CodeAddWindow codeAddWindow) {
		this.codeAddWindow = codeAddWindow;
	}

}
